package com.example.learnandroid;

import java.io.IOException;
import java.util.ArrayList;
import com.churnlabs.ffmpegsample.MainActivity;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.PixelFormat;
import android.hardware.Camera;
import android.media.CamcorderProfile;
import android.media.MediaMetadataRetriever;
import android.media.MediaRecorder;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.TextView;
import android.widget.Toast;

public class MakeGIF_v3 extends Activity {

	private Camera myCamera;
	private MyCameraSurfaceView myCameraSurfaceView;
	private MediaRecorder mediaRecorder;
	private ArrayList<Bitmap> lBitmap;
	private Button myButton;
	private boolean recording;
	private TextView tv_time;
	private CameraTime cam_th;
	private ProgressDialog progressDialog;
	

	private static int camera_time = 20;

	/** Called when the activity is first created. */
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		recording = false;
		requestWindowFeature(Window.FEATURE_NO_TITLE);
		getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
				WindowManager.LayoutParams.FLAG_FULLSCREEN);

		setContentView(R.layout.makegif_v3);

		// Get Camera for preview
		myCamera = getCameraInstance();
		if (myCamera == null) {
			Toast.makeText(MakeGIF_v3.this, "Fail to get Camera",
					Toast.LENGTH_LONG).show();
		}

		myCameraSurfaceView = new MyCameraSurfaceView(this, myCamera);
		FrameLayout myCameraPreview = (FrameLayout) findViewById(R.id.videoview);
		myCameraPreview.addView(myCameraSurfaceView);

		tv_time = (TextView) findViewById(R.id.tv_camera);
		// tv_time.setVisibility(View.INVISIBLE);
		myButton = (Button) findViewById(R.id.startButton);
		myButton.setOnClickListener(myButtonOnClickListener);
	}

	Button.OnClickListener myButtonOnClickListener = new Button.OnClickListener() {

		@Override
		public void onClick(View v) {
			if (recording) {
				// stop recording and release camera
				mediaRecorder.stop(); // stop the recording
				releaseMediaRecorder(); // release the MediaRecorder object

				// finish();
			} else {

				// Release Camera before MediaRecorder start
				releaseCamera();

				if (!prepareMediaRecorder()) {
					Toast.makeText(MakeGIF_v3.this,
							"Fail in prepareMediaRecorder()!\n - Ended -",
							Toast.LENGTH_LONG).show();
					finish();
				}

				mediaRecorder.start();
				recording = true;
				// tv_time.setVisibility(View.VISIBLE);
				myButton.setVisibility(View.INVISIBLE);
				// myButton.setText("STOP");

				cam_th = new CameraTime();
				cam_th.start();

				// stopcam_th.start();

			}
		}
	};

	private Camera getCameraInstance() {
		Camera c = null;
		try {
			c = Camera.open(); // attempt to get a Camera instance
			c.setDisplayOrientation(90);
		} catch (Exception e) {
			// Camera is not available (in use or does not exist)
		}
		return c; // returns null if camera is unavailable
	}

	private boolean prepareMediaRecorder() {
		myCamera = getCameraInstance();
		mediaRecorder = new MediaRecorder();

		myCamera.unlock();
		mediaRecorder.setCamera(myCamera);

		mediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
		mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
		// mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);

		mediaRecorder.setProfile(CamcorderProfile
				.get(CamcorderProfile.QUALITY_HIGH));
		mediaRecorder.setOutputFile("/sdcard/myvideo.mp4");
		mediaRecorder.setVideoSize(480, 320);
		mediaRecorder.setVideoFrameRate(3);

		mediaRecorder.setPreviewDisplay(myCameraSurfaceView.getHolder()
				.getSurface());

		try {
			mediaRecorder.prepare();
		} catch (IllegalStateException e) {
			releaseMediaRecorder();
			return false;
		} catch (IOException e) {
			releaseMediaRecorder();
			return false;
		}
		return true;

	}

	@Override
	protected void onPause() {
		super.onPause();
		releaseMediaRecorder(); // if you are using MediaRecorder, release it
								// first
		releaseCamera(); // release the camera immediately on pause event
	}

	private void releaseMediaRecorder() {
		if (mediaRecorder != null) {
			mediaRecorder.reset(); // clear recorder configuration
			mediaRecorder.release(); // release the recorder object
			mediaRecorder = null;
			myCamera.lock(); // lock camera for later use
		}
	}

	private void releaseCamera() {
		if (myCamera != null) {
			myCamera.release(); // release the camera for other applications
			myCamera = null;
		}
	}

	public class MyCameraSurfaceView extends SurfaceView implements
			SurfaceHolder.Callback {

		private SurfaceHolder mHolder;
		private Camera mCamera;

		@SuppressWarnings("deprecation")
		public MyCameraSurfaceView(Context context, Camera camera) {
			super(context);
			mCamera = camera;

			// Install a SurfaceHolder.Callback so we get notified when the
			// underlying surface is created and destroyed.
			mHolder = getHolder();
			mHolder.addCallback(this);
			// deprecated setting, but required on Android versions prior to 3.0
			mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
		}

		@Override
		public void surfaceChanged(SurfaceHolder holder, int format,
				int weight, int height) {
			// If your preview can change or rotate, take care of those events
			// here.
			// Make sure to stop the preview before resizing or reformatting it.
			//mCamera.setDisplayOrientation(90);
			if (mHolder.getSurface() == null) {
				// preview surface does not exist
				return;
			}

			// stop preview before making changes
			try {
				mCamera.stopPreview();
			} catch (Exception e) {
				// ignore: tried to stop a non-existent preview
			}
			
			 Camera.Parameters p = mCamera.getParameters();
			 p.set("jpeg-quality", 100);
			 p.set("orientation", "landscape");
			 p.set("rotation", 90);
			 p.setPictureFormat(PixelFormat.JPEG);
			 p.setPreviewSize(height, weight);// here w h are reversed
			 mCamera.setParameters(p);
			 
			// make any resize, rotate or reformatting changes here
			/*
			 * Camera.Parameters parameters = mCamera.getParameters();
			 * List<Camera.Size> previewSizes =
			 * parameters.getSupportedPreviewSizes(); Camera.Size previewSize =
			 * previewSizes.get(0); parameters.setPreviewSize(previewSize.width,
			 * previewSize.height); mCamera.setParameters(parameters);
			 */
			// start preview with new settings
			try {
				mCamera.setPreviewDisplay(mHolder);
				mCamera.startPreview();

			} catch (Exception e) {
			}
		}

		@Override
		public void surfaceCreated(SurfaceHolder holder) {
			// The Surface has been created, now tell the camera where to draw
			// the preview.
			try {
				//mCamera.setDisplayOrientation(90);
				mCamera.setPreviewDisplay(holder);
				mCamera.startPreview();
			} catch (IOException e) {
			}
		}

		@Override
		public void surfaceDestroyed(SurfaceHolder holder) {
			mCamera.release();

		}
	}

	private void convertVideoToBitmapList2() {
		try {
			long start = System.currentTimeMillis();
			int width = 320;
			int height = 240;

			// extract video to bitmap

			MainActivity.openFile("/sdcard/myvideo.mp4");

			Bitmap mBitmap = BitmapFactory.decodeResource(getResources(),
					R.drawable.test0);
			lBitmap = new ArrayList<Bitmap>();
			lBitmap.clear();
			for (int i = 0; i < 100; i++) {
				System.out.println(i);
				if (i % 5 == 0) {
					Bitmap bm = mBitmap.copy(Bitmap.Config.ARGB_8888, true);
					MainActivity.drawFrame(bm, width, height, 1);
					lBitmap.add(bm);
				} else {
					MainActivity.drawFrame(mBitmap, width, height, 0);
				}

			}

			long stop = System.currentTimeMillis();
			System.out.println(stop - start);

		} catch (Exception e) {
			System.out.println(e.getMessage());
		}
	}

	private void convertVideoToBitmapList() {
		try {
			long start = System.currentTimeMillis();
			int width = 320;
			int height = 240;

			// extract video to bitmap
			MediaMetadataRetriever mRetriever = new MediaMetadataRetriever();
			mRetriever.setDataSource("/sdcard/myvideo2.mp4");

			lBitmap = new ArrayList<Bitmap>();

			for (int i = 0; i < 20; i++) {
				Bitmap bm = mRetriever.getFrameAtTime(330000 * i);
				lBitmap.add(bm);

			}
			long stop = System.currentTimeMillis();
			System.out.println(stop - start);

		} catch (Exception e) {
			System.out.println(e.getMessage());
		}
	}

	private class LoadViewTask extends AsyncTask<Void, Integer, Void> {
		ProgressDialog progressDialog;

		@Override
		protected void onPreExecute() {
			progressDialog = ProgressDialog.show(MakeGIF_v3.this, "Loading...",
					"Loading GIF preview, please wait...", false, false);
		}

		@Override
		protected Void doInBackground(Void... arg0) {
			convertVideoToBitmapList2();
			return null;
		}

		@Override
		protected void onPostExecute(Void result) {
			// close the progress dialog
			progressDialog.dismiss();
			Intent intent = new Intent(MakeGIF_v3.this, PreviewGIF.class);
			Images.listImage = lBitmap;
			startActivity(intent);
			finish();
		}
	}

	private class CameraTime extends Thread {
		public void run() {
			while (true) {
				MakeGIF_v3.this.runOnUiThread(new Runnable() {

					@Override
					public void run() {
						System.out.println(camera_time);
						tv_time.setText(String.valueOf(camera_time));
					}
				});

				try {
					sleep(335);

					camera_time--;
					if (camera_time == 0) {
						camera_time = 20;
						mediaRecorder.stop(); // stop the recording
						releaseMediaRecorder(); // release the MediaRecorder
												// object

						MakeGIF_v3.this.runOnUiThread(new Runnable() {

							@Override
							public void run() {
								progressDialog = ProgressDialog.show(
										MakeGIF_v3.this, "Loading...",
										"Loading GIF preview, please wait...",
										false, false);
							}

						});
						convertVideoToBitmapList2();
						MakeGIF_v3.this.runOnUiThread(new Runnable() {

							@Override
							public void run() {
								progressDialog.dismiss();
								Intent intent = new Intent(MakeGIF_v3.this,
										PreviewGIF.class);

								Images.listImage = lBitmap;
								startActivity(intent);
								MakeGIF_v3.this.finish();
							}

						});
						break;
					}
				} catch (Exception e) {
					e.printStackTrace();
					this.interrupt();
				}
			}
		}

	}

}